﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Drawing;
using XMLSchemaExtractor.Generator.DTDEntities;

namespace XMLSchemaExtractor.Generator
{
    class ORASS
    {
        private DTD dtdObject;
        private Graphics graphic;
        private static String messages;
        public ORASS(string filePath, Graphics graphic)
        {
            this.dtdObject = new DTD(filePath);
            this.graphic = graphic;
            messages = "";
        }

        public Graphics GetSchema()
        {
            Draw(dtdObject);
            return graphic;

        }

        private void Draw(DTD dtdObject)
        {
            SortedDictionary<String, ElementDetails> elementDetailDictionary = dtdObject.GetElements();
            List<String> listOfElements = dtdObject.GetOrderedElementNames();
            ElementDetails topLevel = elementDetailDictionary[listOfElements[0]];
            DrawElement(topLevel, null, elementDetailDictionary, 0, 0);
        }

        private void DrawElement(ElementDetails element, DEntity dParent, SortedDictionary<String, ElementDetails> elementDetailDictionary, int count, int position)
        {
            // if Parent is null this is probabilt the root element/ancestor element
            if (dParent == null)
            {
                DEntity dEle = new DEntity(element.name, 10, 10, dParent,count,position);
                dEle.Draw(graphic);
                int childCount = 0;
                //
                foreach (ChildDetails child in element.childSeq)
                {

                    DrawChildren(child, dEle,  elementDetailDictionary, element.children.Count, childCount);
                    childCount++;
                }
            }
            else
            {
                DEntity dEle = new DEntity(element.name, (dParent.x + dParent.width) + (position * 100),  dParent.y , dParent, count, position);

                dEle.Draw(graphic);
                if (element.children.Count <= 0 && element.attributes.Count <= 0)
                {
                    if (element.hasCharacterContent)
                    {
                        messages += dParent.Name+ "."+element.name + " might be an attribute.\n";
                    }
                }
                else
                {
                    int childCount = 0;
                    foreach (ChildDetails child in element.childSeq)
                    {
                        
                        DrawChildren(child, dEle, elementDetailDictionary, element.children.Count, childCount);

                        childCount++;
                    }
                    int attributeCount = 0;
                    
                    foreach (var attribute in element.attributes)
                    {
                        DrawAttributes(attribute.Value, dEle, element.attributes.Count, attributeCount);
                        attributeCount++;
                    }
                }
            }

        }
        private void DrawChildren(ChildDetails child, DEntity dParent, SortedDictionary<String, ElementDetails> elementDetailDictionary, int count, int position)
        {
            if (!child.optional)
            {

                DrawElement(elementDetailDictionary[child.name], dParent, elementDetailDictionary, count, position);

            }

        }
        private void DrawAttributes(AttributeDetails attribute, DEntity dParent, int count, int position)
        {

            if (attribute.unique)  
            {
                if (attribute.name == "id" || attribute.name == "idref")
                {
                    messages += dParent.Name+ "." +attribute.name + " is assumed a key since values are unique and the name contains id.\n";
                    DKeyAttribute key = new DKeyAttribute(dParent, attribute.name, count, position);
                    key.Draw(graphic);
                }
                else
                {
                    messages += dParent.Name+ "." +attribute.name + " might be a key since values are unique. \n";
                }
            }
            else
            {
                DNonPrimeAttribute dAttribute = new DNonPrimeAttribute(dParent, attribute.name, count, position);
                dAttribute.Draw(graphic);
            }
        }
        public string[] GetMessage()
        {
            
            return messages.Split('\n');
        }
    }
}
